package com.duobaoyu.dby.supply.biz.client.boundary.message;

import com.duobaoyu.dby.channel.adapter.enums.ChannelCodeEnum;
import com.duobaoyu.dby.channel.adapter.enums.biz.message.MessageTypeEnum;
import com.duobaoyu.dby.channel.boundary.bean.message.param.QueryMessageParam;
import com.duobaoyu.dby.channel.boundary.bean.message.param.RemoveMessageParam;
import com.duobaoyu.dby.channel.boundary.bean.message.result.QueryMessageResult;
import com.duobaoyu.dby.channel.boundary.bean.message.result.RemoveMessageResult;
import com.duobaoyu.dby.channel.boundary.template.SupplyChannelTemplate;
import com.duobaoyu.dby.channel.strategy.bean.MessagePull;
import com.duobaoyu.dby.channel.strategy.bean.MessagePullResult;
import com.duobaoyu.dby.common.core.constant.CommonConstants;
import com.duobaoyu.dby.supply.biz.client.boundary.message.bean.bo.MessagePullBO;
import com.duobaoyu.dby.supply.biz.client.boundary.message.bean.bo.QueryMessageBO;
import com.duobaoyu.dby.supply.biz.client.boundary.message.bean.bo.RemoveMessageBO;
import com.duobaoyu.dby.supply.biz.client.boundary.message.bean.dto.MessagePullDTO;
import com.duobaoyu.dby.supply.biz.client.boundary.message.bean.dto.QueryMessageDTO;
import com.duobaoyu.dby.supply.biz.client.boundary.message.bean.dto.RemoveMessageDTO;
import com.duobaoyu.dby.supply.biz.constant.SupplyChainConstants;
import com.duobaoyu.dby.supply.biz.converter.ChannelMessageConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author liyang
 * @version 1.0.0
 * @ClassName ChannelPullMessageBoundaryClient
 * @createTime 15:53:00 2023/10/10
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChannelPullMessageBoundaryClient {

    private final SupplyChannelTemplate supplyChannelTemplate;
    private final ChannelMessageConverter channelMessageConverter;

    /**
     * 拉取渠道消息
     * @param queryMessage
     * @return
     */
    public QueryMessageBO pullChannelMessage(QueryMessageDTO queryMessage) {
        QueryMessageParam param = channelMessageConverter.toQueryMessageParam(queryMessage);
        QueryMessageResult queryMessageResult = supplyChannelTemplate.pullMessage(param);
        return channelMessageConverter.toQueryMessage(queryMessageResult);
    }

    /**
     * 删除渠道消息
     * @param removeMessage
     * @return
     */
    public RemoveMessageBO removeChannelMessage(RemoveMessageDTO removeMessage) {
        RemoveMessageParam param = channelMessageConverter.toRemoveMessageParam(removeMessage);
        RemoveMessageResult removeMessageResult = supplyChannelTemplate.removeMessage(param);
        return channelMessageConverter.toRemoveMessage(removeMessageResult);
    }

    /**
     * 拉取消息统一处理入口 (默认删除渠道消息)
     * @param messagePull
     * @return
     */
    public MessagePullBO pullChannelMessageHandler(MessagePullDTO messagePull) {
        MessagePull message = channelMessageConverter.toMessagePull(messagePull);
        MessagePullResult messagePullResult = supplyChannelTemplate.pullMessageHandler(message);
        return channelMessageConverter.toMessagePull(messagePullResult);
    }

    /**
     * 拉取消息统一处理入口
     * @param messagePull
     * @param isRemoveChannelMessage 是否删除渠道消息 true - 删除； false - 不删除
     * @return
     */
    public MessagePullBO pullChannelMessageHandler(MessagePullDTO messagePull,boolean isRemoveChannelMessage) {
        MessagePull message = channelMessageConverter.toMessagePull(messagePull);
        MessagePullResult messagePullResult = supplyChannelTemplate.pullMessageHandler(message, isRemoveChannelMessage);
        return channelMessageConverter.toMessagePull(messagePullResult);
    }

    /**
     * 循环处理渠道消息
     * @param channelCodeEnum
     * @param messageTypeEnum
     */
    public void loopPullChannelMessage(ChannelCodeEnum channelCodeEnum, MessageTypeEnum messageTypeEnum,String configUniqueKey) {
        int index = CommonConstants.ZERO;
        do {
            MessagePullDTO messagePull = MessagePullDTO.builder()
                    .channelCode(channelCodeEnum.getValue())
                    .configUniqueKey(configUniqueKey)
                    .messageType(messageTypeEnum.getValue())
                    .pageNo(CommonConstants.ONE)
                    .pageSize(CommonConstants.HUNDRED)
                    .build();
            MessagePullBO messagePullResult = null;
            try {
                messagePullResult = this.pullChannelMessageHandler(messagePull);
            } catch (Throwable e) {
                log.warn("渠道{}拉取消息{}异常: error => {}",channelCodeEnum.getAlias(),messageTypeEnum.getDescribe(), ExceptionUtils.getStackTrace(e));
            }
            if(Objects.isNull(messagePullResult)) {
                break;
            }
            index++;
        } while (index <= SupplyChainConstants.MAX_SPIN_COUNT);
    }

    public MessagePullBO pullChannelMessage(ChannelCodeEnum channelCodeEnum, MessageTypeEnum messageTypeEnum,String configUniqueKey, Integer pageNo, Integer pageSize) {
        MessagePullDTO messagePull = MessagePullDTO.builder()
                .channelCode(channelCodeEnum.getValue())
                .configUniqueKey(configUniqueKey)
                .messageType(messageTypeEnum.getValue())
                .pageNo(pageNo)
                .pageSize(pageSize)
                .build();
        return this.pullChannelMessageHandler(messagePull);
    }
}
